
public class ThreadDemo {
    static int np = 4;
    static int nc = 4;
    static int nbuf = 10;
    public static void main(String[] args) {
        Buffer buffer = new Buffer(nbuf);//共享内存
        Producer[] producers = new Producer[np];
        Consumer[] consumers = new Consumer[nc];
        for(int i=0; i<np; i++){
            producers[i] = new Producer(buffer, i);
            producers[i].start();
            System.out.println("启动生产者线程"+i);
        }
        for(int i=0; i<nc; i++){
            consumers[i] = new Consumer(buffer, i);
            consumers[i].start();
            System.out.println("启动消费者线程"+i);
        }
        
        // try{
        //     for(int i=0; i<np; i++){
                
        //         producers[i].join();
        //     }
        //     for(int i=0; i<nc; i++){
        //         consumers[i].join();
        //     }
        // }catch(Exception e){
        //     e.printStackTrace();
        // }

    }
}

class Producer extends Thread{
    private Buffer buffer;
    private int id;
    public Producer(Buffer buffer, int id){
        this.id = id;
        this.buffer = buffer;//传递对象引用，指向同一个对象
    }
    public void run(){
        for(int i=0; i<10; i++){//可插入其他线程过程
            buffer.put((int) (Math.random()*100), id,i+1);
        }
        System.out.println("生产者进程"+id+"结束");
    }
}

class Consumer extends Thread{
    private Buffer buffer;
    private int id;
    public Consumer(Buffer buffer, int id){
        this.buffer = buffer;
        this.id = id;
    }
    public void run(){
        for(int i=0; i<10; i++){
            buffer.get(id,i+1);
        }
        System.out.println("消费者进程"+id+"结束");
    }
} 
class Buffer{
    private int[] goods;
    private int head;
    private int tail;
    private int count;
    private int nbuf;
    public Buffer(int nbuf){
        head = 0;
        tail = 0;
        this.nbuf = nbuf;
        goods = new int[nbuf];
        count = 0;
    }
    //get、put方法线程同步，原子操作
    public synchronized void get(int id, int num){
        while(count <= 0){
            try{
                System.out.println("消费者"+id+"号发现没有物品");
                wait();//线程通信
            }catch(InterruptedException e){
                e.printStackTrace();
            }
        }

        head = (head+1)%nbuf;
        count--;
        System.out.println("消费者"+id+"号取走了物品"+goods[head]+";他总计取走物品"+num+"件;缓冲区剩余物品"+count);
        
        notifyAll();//线程通信
        //return goods[head];

 
    }

    public synchronized void put(int value,int id,int num){
        while(count>=nbuf){
            try{
                System.out.println("生产者"+id+"号发现缓冲区已满");
                wait();
            }catch(InterruptedException e){
                e.printStackTrace();
            }
        }

        tail = (tail+1)%nbuf;
        goods[tail] = value;
        count++;
        System.out.println("生产者"+id+"号生产了物品"+goods[tail]+";他总生产物品"+num+"件;缓冲区剩余物品"+count);
        notifyAll();
    }
}